使用 Kind 部署 KubeSphere 实验环境
现在安装 Kubernetes 集群已经变得越来越简单了,Kubernetes in Docker(KinD)这个工具就可以通过创建容器来作为 Kubernetes 的节点,我们只需要在机器上安装 Docker 就可以使用,它允许我们在很短的时间内就启动一个多节点的集群,而不依赖任何其他工具或云服务商。
本文将介绍 Kind 中 extra-port-mappings,kubernetes-version,image-registry,api-server-acl 等基本配置。 并带有一个 kubesphere 部署示例,还演示了在不删除 Kind 集群的情况下的暂停和重启,以及 Kind 开启 IPVS 导致相关错误的排查记录。
RTFM
在开始之前我们需要读一下相关文档。
- 指定具体的集群版本可以查看 kubernetes-version 。
- 默认情况下你无法访问 Kind 集群的 nodeport 你需要通过 nodeport with port mappings 添加外部端口映射到宿主机。
- 出于安全原因默认情况下 Kind 部署的 api-server 仅允许 127.0.0.1 访问,你可以参考 api-server 进行更改,如改为宿主机 IP 实现外部访问 。
否则你将收到报错
The connection to the server {YourIP}:6443 was refused - did you specify the right host or port?
- 手动指定仓库地址 image-registry 。
- 参考 kubeadm-config-patches 可以对 kubeadm 进行额外的参数调整
新建 Kind 集群
Kind 配置文件参考 kubesphere.yaml
kind: Cluster
apiVersion: kind.x-k8s.io/v1alpha4
networking:
apiServerAddress: "127.0.0.1" # 默认 "127.0.0.1" ,如果你需要在外部访问则需要修改为 "Node IP"
apiServerPort: 6443
kubeProxyMode: "iptables" # 默认 "iptables", Kind 中开启 IPVS 可能会导致错误 https://github.com/kubernetes-sigs/kind/issues/2326
podSubnet: "10.244.0.0/16"
serviceSubnet: "10.96.0.0/12"
disableDefaultCNI: false # 默认 "false" ,如果你需要自己部署 CNI 则设为 "true"
containerdConfigPatches: # 根据需要指定镜像仓库
# 下面列举了一些镜像加速地址。
# - Docker 中国区官方镜像加速:https://registry.docker-cn.com
# - 网易镜像加速:http://hub-mirror.c.163.com
# - 中国科技大学镜像加速:https://docker.mirrors.ustc.edu.cn
# - 腾讯云镜像加速:https://mirror.ccs.tencentyun.com
- |-
[plugins."io.containerd.grpc.v1.cri".registry.mirrors."docker.io"]
endpoint = ["https://mirror.ccs.tencentyun.com"]
nodes:
- role: control-plane
extraPortMappings:
# 只在一台节点配置 nodePort 端口映射既可,
# 因为当指定 nodePort 后 k8s 集群每台节点都会暴露 nodePort ,访问任意一个既可路由到 ClusterIP Service。
- containerPort: 30880 # containerPort(kind 节点想要映射到主机的 nodePort 端口)默认 30000-32767
hostPort: 30880 # hostPort(宿主机端口)默认 0-65535 (注意不可重复)
protocol: tcp # 默认 "tcp"
listenAddress: "0.0.0.0" # 默认 "0.0.0.0"
- containerPort: 30080
hostPort: 80
protocol: tcp
listenAddress: "0.0.0.0"
image: kindest/node:v1.21.14@sha256:9d9eb5fb26b4fbc0c6d95fa8c790414f9750dd583f5d7cee45d92e8c26670aa1 # images 发布地址 https://github.com/kubernetes-sigs/kind/releases
- role: worker
image: kindest/node:v1.21.14@sha256:9d9eb5fb26b4fbc0c6d95fa8c790414f9750dd583f5d7cee45d92e8c26670aa1
创建集群
kind create cluster --name kubesphere --config kubesphere.yaml
删除集群
kind delete cluster --name kubesphere
测试用例
这里我们对 NodePort 进行一个简单地测试,看看是否能正常访问。
创建测试 pod
kubectl run nginx-demo --image nginx --port 80
创建 NodePort 类型的 Service ,并指定 nodePort: 30080
cat <<EOF | kubectl apply -f -
apiVersion: v1
kind: Service
metadata:
creationTimestamp: null
labels:
run: nginx-demo
name: nginx-demo
spec:
ports:
- port: 80
protocol: TCP
targetPort: 80
nodePort: 30080
selector:
run: nginx-demo
type: NodePort
status:
loadBalancer: {}
EOF
在创建集群时候我们将 30080 映射到了本地的 80 端口,所以在本地使用 curl -I http://localhost:80/
来验证结果
❯ curl -I http://localhost:80/
HTTP/1.1 200 OK
Server: nginx/1.23.3
Date: Wed, 04 Jan 2023 03:49:50 GMT
Content-Type: text/html
Content-Length: 615
Last-Modified: Tue, 13 Dec 2022 15:53:53 GMT
Connection: keep-alive
ETag: "6398a011-267"
Accept-Ranges: bytes
部署 KubeSphere
KubeSphere 安装十分简单。
- Kubernetes 版本要求 v1.19.x、v1.20.x、v1.21.x、* v1.22.x、* v1.23.x 和 * v1.24.x。带星号的版本可能出现边缘节点部分功能不可用的情况。
- Kubernetes 集群需存在默认的 StorageClass
- 参考安装文档
我们本次实用的是 Kubernetes v1.21.14,而且 Kind 已经创建了一个默认的 StorageClass 来配置本地存储。
❯ kubectl get sc
NAME PROVISIONER RECLAIMPOLICY VOLUMEBINDINGMODE ALLOWVOLUMEEXPANSION AGE
standard (default) rancher.io/local-path Delete WaitForFirstConsumer false 96m
我们符合准备工作的要求,下面让我们来安装 KubeSphere 吧
# 部署 KubeSphere
kubectl apply -f https://github.com/kubesphere/ks-installer/releases/download/v3.3.1/kubesphere-installer.yaml
kubectl apply -f https://github.com/kubesphere/ks-installer/releases/download/v3.3.1/cluster-configuration.yaml
# 查看安装日志
kubectl logs -n kubesphere-system $(kubectl get pod -n kubesphere-system -l 'app in (ks-install, ks-installer)' -o jsonpath='{.items[0].metadata.name}') -f
# 查看 Service 名字
kubectl get svc/ks-console -n kubesphere-system
你可以参考启用热插拔组件继续安装其他组件,这里不再赘述。
我们部署 Kind 时已将 NodePort 30880 映射到了宿主机 30880 端口,现在打开浏览器访问 http://localhost:30880/
既可。默认帐户 admin
默认密码 P@88w0rd
。
Kind 集群状态查看
我们可以使用 --format 来对结果进行格式化输出,使用 --filter 进行对结果进行过滤。
KIND_CLUSTER=kubesphere
# 列出 Kind cluster 容器列表
docker ps -a \
--format "table {{.ID}}\t{{.Image}}\t{{.Names}}\t{{.Status}}\t{{.Networks}}" \
--filter "label=io.x-k8s.kind.cluster=${KIND_CLUSTER}"
# 列出 Kind cluster 资源状态
docker stats $(docker ps -q --filter "label=io.x-k8s.kind.cluster=kubesphere")
# 列出 Kind cluster 容器 IP
docker inspect $(docker ps -q --filter "label=io.x-k8s.kind.cluster=${KIND_CLUSTER}") \
--format='{{ printf "%-50s" .Name}} {{range .NetworkSettings.Networks}}{{.IPAddress}} {{end}}'
注意本文 Kind 创建的集群名字为 kubesphere
请视情况更改变量 ${KIND_CLUSTER}
。
可以通过 kind get clusters
和 kubectl config get-clusters
获取你正在使用的集群名字
❯ kind get clusters
kubesphere
❯ kubectl config get-clusters
NAME
kind-kubesphere
Kind 集群暂停与开启
创建集群后,是否可以在不删除集群的情况下停止并重新启动它?参考这个 Issue
KIND_CLUSTER=kubesphere
# 暂停容器 此时容器 STATUS 变为 (Paused)
docker pause $(docker ps -q --filter "label=io.x-k8s.kind.cluster=kubesphere")
# 取消暂停容器
docker unpause $(docker ps -q --filter "label=io.x-k8s.kind.cluster=kubesphere")
Troubleshooting
IPVS 和 DNS 解析错误排查
参考 issues/2326
在 Kind 中开启 networking.kubeProxyMode: "ipvs"
时,
networking:
kubeProxyMode: "ipvs"
部分 k8s 版本会出现无法初始化 node 错误,node 节点会一直卡在 Starting kube-proxy
。
❯ kubectl describe node
Events:
Type Reason Age From Message
---- ------ ---- ---- -------
Normal NodeHasSufficientMemory 15m (x8 over 15m) kubelet Node kubesphere-worker status is now: NodeHasSufficientMemory
Normal NodeHasNoDiskPressure 15m (x8 over 15m) kubelet Node kubesphere-worker status is now: NodeHasNoDiskPressure
Normal RegisteredNode 15m node-controller Node kubesphere-worker event: Registered Node kubesphere-worker in Controller
Normal Starting 14m kube-proxy Starting kube-proxy.
Normal Starting 33s kubelet Starting kubelet.
Normal NodeAllocatableEnforced 33s kubelet Updated Node Allocatable limit across pods
Normal NodeHasSufficientMemory 27s (x7 over 33s) kubelet Node kubesphere-worker status is now: NodeHasSufficientMemory
Normal NodeHasNoDiskPressure 27s (x7 over 33s) kubelet Node kubesphere-worker status is now: NodeHasNoDiskPressure
Normal NodeHasSufficientPID 27s (x7 over 33s) kubelet Node kubesphere-worker status is now: NodeHasSufficientPID
Normal Starting 22s kube-proxy Starting kube-proxy.